package com.suduku.calc;

import com.suduku.entity.Box;
import com.suduku.entity.Chain;
import com.suduku.util.SudoUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 数链-多数链（由多条数链组成，不确定几条） <br/>
 */
public class SuLianMoreCalc extends AbstractCalc {

    /**
     * 1、 遍历所有数字
     * 2、 找出行，列，宫内，只有两个候选值由n的空白格
     * 3、 查找关系 以 B1--B2..B3--B4..B5--B6的关系（--当前区域只有两个空白格，..只要行列宫由一个相等即可）
     * 4、 清除守卫端点共同作用的空白格，清除候选值n
     */
    @Override
    Box solve() {
        // 遍历数字
        for(Integer n : Box.INIT_LIST) {
            // 查找出全部的再区域内只有两个空白格的强链
            List<Chain> allChainList = getAllTrueChain(n);
            // 从全部强链中，查找关联性
            for(Chain firstChain : allChainList) {
                // 首届点起步
                firstChain.setPre(null);
                List<Chain> usedList = SudoUtil.getList();
                addNext(firstChain, usedList, allChainList);

            }
        }
        return null;
    }

    private void addNext(Chain chain, List<Chain> usedList, List<Chain> allChainList) {

    }

    /**
     * 功能描述: 查找全部的强链 <br/>
     *
     * @param n 候选值
     * @return "java.ut qil.List<com.suduku.entity.Chain>"
     */
    private List<Chain> getAllTrueChain(Integer n) {
        Set<Chain> set = new HashSet<>();
        // 获取区域内的强链
        set.addAll(getAreaTrueChain(getGentries(), n));
        set.addAll(getAreaTrueChain(getXentries(), n));
        set.addAll(getAreaTrueChain(getYentries(), n));
        return new ArrayList<>(set);
    }

    /**
     * 功能描述: 获取区域内的强链 <br/>
     *
     * @param entries 区域列表
     * @param n 候选数字
     * @return "java.util.List<com.suduku.entity.Chain>"
     */
    private List<Chain> getAreaTrueChain(Set<Map.Entry<Integer, List<Box>>> entries, Integer n) {
        List<Chain> list = new ArrayList<>();
        for (Map.Entry<Integer, List<Box>> entry : entries) {
            List<Box> boxes = entry.getValue().stream()
                    .filter(b -> b.isBlank() && b.getCList().contains(n))
                    .collect(Collectors.toList());
            if(boxes.size() == 2) {
                list.add(new Chain(boxes));
            }
        }
        return list;
    }

}
